<template>
  <div class="app-container">
    <el-card class="filter-container" shadow="never">
      <div>
        <i class="el-icon-search"></i>
        <span>筛选搜索</span>
        <el-button
            size="small"
            style="float:right"
            type="primary"
            @click="handleSearchList()">
          查询搜索
        </el-button>
        <el-button
            size="small"
            style="float:right;margin-right: 15px"
            @click="handleResetSearch()">
          重置
        </el-button>
      </div>
      <div style="margin-top: 15px">
        <el-form :inline="true" :model="listQuery" label-width="auto" size="small">
          <el-form-item label="项目：">
            <el-select v-model="listQuery.projectId" style="width:100%"
                       @change="projectChangeThenInitDatasourceOption();handleSearchList()">
              <el-option
                  v-for="item in allProjectListOption"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="数据源：">
            <el-select v-model="listQuery.datasourceId" clearable filterable no-data-text="请先选择项目"
                       style="width:100%" @change="handleSearchList">
              <el-option
                  v-for="item in datasourceOption"
                  :key="item.id"
                  :label="item.remark"
                  :value="item.id">
              </el-option>
            </el-select>
          </el-form-item>
        </el-form>
      </div>
    </el-card>

    <el-card class="operate-container" shadow="never">
      <i class="el-icon-tickets"></i>
      <span>数据列表</span>
    </el-card>

    <div class="table-container">
      <el-table ref="roleTable"
                v-loading="listLoading"
                :data="list"
                :default-sort="{prop: 'createTime', order: 'descending'}"
                border style="width: 100%;">
        <el-table-column type="expand">
          <template slot-scope="scope">
            <el-card header="更多操作">
              <div
                  v-if="currentProject.templateConfig.additionTableMethodComponentList && currentProject.templateConfig.additionTableMethodComponentList.length>0">
                <div v-for="item in currentProject.templateConfig.additionTableMethodComponentList" :key="item.id">
                  <el-link icon="el-icon-circle-plus-outline" type="primary"
                           @click.stop="processAdditionTableMethod(scope.row.tableName, item)">{{ item.btnName }}
                  </el-link>
                  <span style="color: grey">：{{ item.desc }}</span>
                </div>
              </div>
              <div v-else>
                暂无更多操作
              </div>
            </el-card>
          </template>
        </el-table-column>
        <el-table-column align="center" label="表" prop="tableName" show-overflow-tooltip sortable>
          <template slot-scope="scope">
            {{ scope.row.tableName + '-' + scope.row.tableComment }}
          </template>
        </el-table-column>
        <el-table-column align="center" label="前端代码" prop="tableComment" width="200">
          <template slot-scope="scope">
            <el-popover
                placement="top-start"
                title="请选择生成文件类型"
                trigger="hover">
              <div style="width: 260px">
                <div v-if="scope.row.frontTips" style="margin-bottom: 10px;border-bottom: solid 1px #eee">
                  <div style="color: red">配置有改动，需重新生成代码</div>
                </div>
                <el-checkbox-group v-model="generationVueType" size="medium">
                  <el-checkbox key="api" label="api">api接口</el-checkbox>
                  <el-checkbox key="view" label="view">view页面</el-checkbox>
                  <el-button :loading="listLoading" size="mini"
                             style="margin-left: 10px"
                             type="primary"
                             @click="handleCreateAllVue(scope.row.tableName)">
                    生成
                  </el-button>
                </el-checkbox-group>
              </div>
              <el-badge slot="reference" :value="scope.row.frontTips?'新':''" type="danger">
                <el-button size="mini" type="primary">生成</el-button>
              </el-badge>
            </el-popover>
          </template>
        </el-table-column>
        <el-table-column align="center" label="后端代码" prop="tableComment" width="200">
          <template slot-scope="scope">
            <el-popover
                placement="top-start"
                title="请选择生成文件类型"
                trigger="hover">
              <div style="width: 480px">
                <div v-if="scope.row.backTips" style="margin-bottom: 10px;border-bottom: solid 1px #eee">
                  <div style="color: red">配置有改动，需重新生成代码</div>
                </div>
                <el-checkbox-group v-model="generationCRUDType" size="medium">
                  <el-checkbox key="entity" label="entity">实体类代码</el-checkbox>
                  <el-checkbox key="dao" label="dao">dao代码</el-checkbox>
                  <el-checkbox key="mapper" label="mapper">mapper代码</el-checkbox>
                  <el-checkbox key="service" label="service">service代码</el-checkbox>
                  <el-checkbox key="serviceImpl" label="serviceImpl">serviceImpl代码</el-checkbox>
                  <el-checkbox key="controller" label="controller">controller代码</el-checkbox>
                  <el-button :loading="listLoading" size="mini"
                             style="margin-left: 10px"
                             type="success"
                             @click="handleCreateCRUD(scope.row.tableName)">
                    生成
                  </el-button>
                </el-checkbox-group>
              </div>
              <el-badge slot="reference" :value="scope.row.backTips?'新':''" type="danger">
                <el-button size="mini" type="success">生成</el-button>
              </el-badge>
            </el-popover>
          </template>
        </el-table-column>
        <el-table-column align="center" label="初始化菜单" width="200">
          <template slot="header">
            <span style="margin-right: 5px">初始化菜单</span>
            <el-tooltip content="给当前表新增菜单，添加增删查改权限按钮" effect="light" placement="top">
              <i class="el-icon-question" style="cursor: pointer; color: #999;"></i>
            </el-tooltip>
          </template>
          <template slot-scope="scope">
            <el-button :loading="listLoading" size="mini" type="success" @click="handleCreateMenu(scope.row.tableName)">
              生成菜单
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

  </div>
</template>
<script>
import {createCodePostRequire} from '@/api/createCode'
import {projectPostRequire} from '@/api/project'
import {tablePostRequire} from '@/api/tableConfig'

const defaultListQuery = {
  projectId: undefined,
  datasourceId: undefined,
}

export default {
  name: 'tableToCode',
  data() {
    return {
      datasourceOption: [],
      generationVueType: ['view', 'api'],
      generationCRUDType: ['service', 'serviceImpl', 'entity', 'dao', 'mapper', 'controller'],
      listQuery: this.$deepClone(defaultListQuery),
      list: null,
      allProjectListOption: [],
      allProjectJSON: {},
      listLoading: false,
      addDialogVisible: false,
      editDialogVisible: false,
      currentProject: {},
      currentDatasourceId: '',
    }
  },
  created() {
    let currentProject = JSON.parse((localStorage.getItem('currentProject') || "{}"))
    if (currentProject && this.listQuery.projectId == null && currentProject.id != null) {
      this.listQuery.projectId = currentProject.id
    }
    this.getProjectList(() => {
      this.projectChangeThenInitDatasourceOption()
      this.initTableOptionByProjectId();
    })
  },
  methods: {
    projectChangeThenInitDatasourceOption(projectId) {
      this.listQuery.datasourceId = null
      if (projectId == null) {
        projectId = this.listQuery.projectId
      }
      if (projectId == null) {
        return false;
      }

      let projectJsonElement = this.allProjectJSON[projectId];
      let projectDatasource = projectJsonElement.projectDatasource;
      let mutilDatasourceList = projectJsonElement.mutilDatasourceList;
      let datasourceOption = [projectDatasource]
      if (mutilDatasourceList && mutilDatasourceList.length > 0) {
        datasourceOption.push(...mutilDatasourceList)
      } else {
        this.listQuery.datasourceId = projectDatasource.id
      }
      this.datasourceOption = datasourceOption

    },
    handleResetSearch() {
      this.listQuery = this.$deepClone(defaultListQuery)
    },
    handleSearchList() {
      this.initTableOptionByProjectId()
    },
    handleCreateCRUD(tableName) {
      if (this.generationCRUDType.length <= 0) {
        this.$message({
          message: '请选择要生成的文件',
          type: 'error'
        })
        return false;
      }
      this.$confirm('新代码将会覆盖代码，是否继续', '提示', {
        confirmButtonText: '继续',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.listLoading = true
        let params = {
          tableName: tableName,
          projectId: this.currentProject.id,
          datasourceId: this.currentDatasourceId,
          type: this.generationCRUDType.toString()
        }
        createCodePostRequire('createTableCRUD', params).then(response => {
          this.$message({
            type: response.status ? 'success' : 'error',
            message: response.message
          })
        }).finally(() => {
          this.listLoading = false
          this.initTableOptionByProjectId()
        })
      })
    },
    handleCreateMenu(tableName) {
      this.$confirm('将会在sys_menu表中插入菜单以及增删查改的按钮', '提示', {
        confirmButtonText: '继续',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.listLoading = true
        createCodePostRequire('createTableMenu', {
          tableName: tableName,
          projectId: this.currentProject.id,
          datasourceId: this.currentDatasourceId,
        }).then(response => {
          this.$message({
            type: response.status ? 'success' : 'error',
            message: response.message
          })
        }).finally(() => {
          this.listLoading = false
        })
      })
    },
    processAdditionTableMethod(tableName, templateConfig) {
      this.$confirm('确定执行【' + templateConfig.btnName + '】方法吗？', '提示', {
        confirmButtonText: '继续',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.listLoading = true
        createCodePostRequire('processAdditionTableMethod', {
          tableName: tableName,
          projectId: this.currentProject.id,
          datasourceId: this.currentDatasourceId,
          className: templateConfig.methodClass,
          methodName: templateConfig.methodName,
        }).then(response => {
          this.$message({
            type: response.status ? 'success' : 'error',
            message: response.message
          })
        }).finally(() => {
          this.listLoading = false
        })
      })
    },
    handleCreateAllVue(tableName) {
      if (this.generationVueType.length <= 0) {
        this.$message({
          message: '请选择要生成的文件',
          type: 'error'
        })
        return false;
      }
      this.$confirm('新代码将会覆盖旧代码', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.listLoading = true
        createCodePostRequire('createTableVueCode', {
          tableName: tableName,
          projectId: this.currentProject.id,
          datasourceId: this.currentDatasourceId,
          type: this.generationVueType.toString()
        }).then(response => {
          this.$message({
            type: 'success',
            message: response.message
          })
        }).finally(() => {
          this.listLoading = false
          this.initTableOptionByProjectId()
        })
      })
    },
    getProjectList(resolveFn) {
      this.listLoading = true
      projectPostRequire("getAllProjectOption").then(response => {
        this.allProjectListOption = response.data || [];
        if (this.allProjectListOption.length > 0) {
          this.allProjectListOption.forEach(item => {
            this.allProjectJSON[item.id] = item;
          })
          if (resolveFn) {
            resolveFn()
          }
        }
      }).finally(() => {
        this.listLoading = false;
      })
    },
    initTableOptionByProjectId(resolveFn) {
      let projectId = this.listQuery.projectId
      let datasourceId = this.listQuery.datasourceId
      if (!projectId || datasourceId == null) {
        this.$message({
          message: '请先选择项目和数据源',
          type: 'warning'
        })
        return false;
      } else {
        this.listLoading = true
        tablePostRequire('listAllByDatasourceId', this.listQuery).then(response => {
          let listArr = response.data || []
          let projectConfigChangeArr = response.projectConfigRecord || []
          if (projectConfigChangeArr.length > 0) {
            let currentProjectConfig
            for (let i = 0; i < projectConfigChangeArr.length; i++) {
              if (projectConfigChangeArr[i].projectId == projectId) {
                currentProjectConfig = projectConfigChangeArr[i]
                break;
              }
            }
            let datasourceName = ""
            for (let i = 0; i < this.datasourceOption.length; i++) {
              if (this.datasourceOption[i].id == datasourceId) {
                datasourceName = this.datasourceOption[i].mysqlDatabaseName
                break;
              }
            }
            if (currentProjectConfig && (currentProjectConfig.backRebuildTables || (currentProjectConfig.frontRebuildTables))) {
              for (let i = 0; i < listArr.length; i++) {
                const item = listArr[i]
                let backTips = ''
                let frontTips = ''
                let tableName = datasourceName + "." + item.tableName
                let backRebuildTablesArr = (currentProjectConfig.backRebuildTables || "").split(",") || []
                if (backRebuildTablesArr.indexOf(tableName) != -1) {
                  backTips = "1"
                }
                let frontRebuildTablesArr = (currentProjectConfig.frontRebuildTables || "").split(",") || []
                if (frontRebuildTablesArr.indexOf(tableName) != -1) {
                  frontTips = "1"
                }
                item.backTips = backTips
                item.frontTips = frontTips
              }
            }
          }
          this.list = listArr
          this.currentProject = this.allProjectJSON[projectId]
          this.currentDatasourceId = datasourceId
          if (resolveFn) {
            resolveFn()
          }
        }).catch(error => {
          reject(error)
        }).finally(() => {
          this.listLoading = false
        })
      }

    },
  }
}
</script>
<style>
.el-badge__content.is-fixed {
  -webkit-transform: translateY(0%) translateX(100%) !important;
}

.demo-table-expand {
  font-size: 0;
}

.demo-table-expand label {
  /*width: 90px;*/
  color: #99a9bf;
}

.demo-table-expand .el-form-item {
  margin-right: 0;
  margin-left: 10px;
  margin-bottom: 0;
  width: 100%;
}
</style>
